package com.ycsoft.ttctn;

import static java.lang.Math.pow;
import static java.lang.Math.round;

// 定义包格式的描述类。
class FormatIdDesc {
    public String c;
    public String s;
    public String prec;

    public FormatIdDesc() {
        c = "";
        s = "";
        prec = "";
    }

    public int getSize() {
        if (s.isEmpty())
            return 0;
        else {
            try {
                return Integer.parseInt(s);
            } catch (NumberFormatException e) {
                return 0;
            }
        }
    }

    public int getPrec() {
        if (s.isEmpty())
            return 0;
        else {
            try {
                return Integer.parseInt(prec);
            } catch (NumberFormatException e) {
                return 0;
            }
        }
    }
}

// 创建数据包格式化的基础类。
public class MemberFormat {
    /* 把格式化字串的转化为格式化对象。 */
    public static FormatIdDesc decodeFormatId(String formatId) {
        FormatIdDesc desc = new FormatIdDesc();
        desc.c = formatId.substring(0, 1);
        desc.s = formatId.substring(1, 4);
        desc.prec = formatId.substring(5, formatId.length());

        return desc;
    }

    public static int memberSize(String formatId) {
        FormatIdDesc desc = decodeFormatId(formatId);

        return desc.getSize();
    }

    public static String getFormatMember(String formatId, Object value, boolean disp, char fillChar) throws Exception {
        String result = "", value_str;
        long l = 0, lref;
        double d;

        FormatIdDesc desc = decodeFormatId(formatId);
        int size = desc.getSize();
        int prec = desc.getPrec();

        switch (desc.c.toUpperCase()) {
            case "C":  //字符串类型，前填字符达到指定的长度。
                result = YcUtils.padLeft(value.toString(), size, fillChar);
                break;
            case "X":
            case "N":
                // 区分带小数和整数.
                if(prec<=0) {
                    if (value instanceof Long) {
                        l = (long)value;
                    } else if (value instanceof  Integer) {
                        l = (int)value;
                    } else {
                        throw new Exception(String.format("传入的格式化参数(%s)和值(%s)的类型不是Long或Integer!", formatId, value.toString() ));
                    }

                    if (disp) {
                        result = String.format("%d", l);
                    } else {
                        if(size < 0) {
                            lref = round(pow(10, size + 1)) - 1;

                            if (l > lref) l = lref;
                        }
                        result = YcUtils.padLeft(String.format("%d", l), size, fillChar);
                    }
                } else {
                    if (value instanceof Double) {
                        d = (double)value;
                    } else {
                        throw new Exception(String.format("传入的格式化参数(%s)和值(%s)的类型不是Double!", formatId, value.toString() ));
                    }

                    if (disp) {
                        value_str = "%." + String.format("%d", prec) + "f";
                        result = String.format(value_str, d);
                    } else {
                        l = round(d * pow(10, prec));
                        result = YcUtils.padLeft(String.format("%d", l), size, fillChar);
                    }
                }
                break;
            case "R":
                result = YcUtils.padLeft(value.toString(), size, fillChar);
                break;
            case "H":
                // 暂按原值返回.
                result = YcUtils.padLeft(value.toString(), size, fillChar);
                break;
            case "B":
                // 区分带小数和整数.
                if(prec<=0) {
                    if (value instanceof Long) {
                        l = (long)value;
                    } else if (value instanceof  Integer) {
                        l = (int)value;
                    } else {
                        throw new Exception(String.format("传入的格式化参数(%s)和值(%s)的类型不是Long或Integer!", formatId, value.toString() ));
                    }

                    if (disp) {
                        result = String.format("%d", l);
                    } else {
                        if(size < 0) {
                            lref = round(pow(10, size + 1)) - 1;

                            if (l > lref) l = lref;
                        }
                        result = YcUtils.padLeft(String.format("%x", l), size, fillChar);
                    }
                } else {
                    if (value instanceof Double) {
                        d = (double)value;
                    } else {
                        throw new Exception(String.format("传入的格式化参数(%s)和值(%s)的类型不是Double!", formatId, value.toString() ));
                    }

                    if (disp) {
                        value_str = "%." + String.format("%d", prec) + "f";
                        result = String.format(value_str, d);
                    } else {
                        l = round(d * pow(10, prec));
                        result = YcUtils.padLeft(String.format("%x", l), size, fillChar);
                    }
                }
                break;
             default:
                 throw new Exception(String.format("未实现的格式(%s)", formatId));
        }

        return result;
    }

    public static String getFormatMember(String formatId, Object value, boolean disp) throws Exception {
        return  getFormatMember(formatId, value, disp, '0');
    }

    public static String setFormatMember(String formatId, String value) throws Exception {
        String result = "", value_str;
        long l = 0, lref;
        double d;

        FormatIdDesc desc = decodeFormatId(formatId);
        int size = desc.getSize();
        int prec = desc.getPrec();

        if (value.length() != size) {
            throw new Exception(String.format("程序逻辑错误: 截取的字符串(%s)长度与格式化符(%s)不一致！",  value, formatId));
        }

        switch (desc.c.toUpperCase()) {
            case "C":
                result = value;
                break;
            case "X":
            case "N":
                try {
                    l = Long.parseLong(value);
                } catch (Exception e) {
                    throw new Exception(String.format("截取的字符串(%s)转化为数字失败! 格式化符(%s).",  value, formatId));
                }

                if (prec<=0) {
                    result = String.format("%d", l);
                } else {
                    d = l/pow(10, prec);

                    value_str = "%." + String.format("%d", prec) + "f";
                    result = String.format(value_str, d);
                }
                break;
            case "R":
                //todo: 加入日期的校验.
                result = value;
                break;
            case "H":
                //todo: 加入BCD样式数据校验.
                result = value;
            case "B":
                try {
                    l = Long.parseLong(value, 16);
                } catch (Exception e) {
                    throw new Exception(String.format("截取的字符串(%s)转化为数字失败! 格式化符(%s).",  value, formatId));
                }

                if (prec<=0) {
                    result = String.format("%d", l);
                } else {
                    d = l/pow(10, prec);

                    value_str = "%." + String.format("%d", prec) + "f";
                    result = String.format(value_str, d);
                }
                break;
        }

        return result;
    }

}